<?php
// +----------------------------------------------------------------------
// | IPHP
// +----------------------------------------------------------------------
// | This is an open source and simple PHP FrameWork.
// +----------------------------------------------------------------------
// | Author: wuzhuo
// +----------------------------------------------------------------------

namespace IPHP\DB;

class Mysql implements DataBase {
    protected $conn;    //链接句柄
    protected $error;   //错误信息
    protected $errno;   //错误代码
    protected $prefix;  //表前缀
    protected $sql;     //前一句执行的sql语句

    public function __construct($db_host, $db_port, $db_user, $db_pwd, $db_database, $prefix) {
        if(IS_SAE) {
            $conn = mysql_connect(SAE_MYSQL_HOST_M.':'.SAE_MYSQL_PORT,SAE_MYSQL_USER, SAE_MYSQL_PASS );
            mysql_select_db(SAE_MYSQL_DB, $conn);
        } else {
            $conn = mysql_connect($db_host.':'.$db_port, $db_user, $db_pwd);
            mysql_select_db($db_database, $conn);
        }

        if (!$conn) {
            $this->error = mysql_error();
            $this->errno = mysql_errno();
        }

        $this->conn = $conn;
        $this->prefix = $prefix;        
    }

    /**
     * 执行sql语句，返回解析的数据
     * @param  [type] $sql [description]
     * @return [type]      [description]
     */
    public function exec($sql){
        $this->sql = $sql;
        if($res = mysql_query($sql)) {
            $sql = strtolower($sql);

            if(strpos($sql, "insert") !== false || strpos($sql, "replace") !== false ) {
                //　返回自增id
                return mysql_insert_id();
            } elseif(strpos($sql, "delete") !== false || strpos($sql, "update") !== false) {
                //　返回影响行数
                return mysql_affected_rows();
            } elseif(preg_match("/count|avg|sum|min|max/iUs",$sql)) {
                $ret = mysql_fetch_array($res);
                // 统计类，直接返回结果
                return $ret[0];
            } else {
                //　返回处理好的数据
                $ret = $this->_fetchResult($res);
                $this->freeResult($res);
            }

            return $ret;
        } else {
            $this->error = mysql_error();
            $this->errno = mysql_errno();
            return false;
        }
    }

    /**
     * 获取数据字段
     * @return [type] [description]
     */
    public function getallfields($tablename) {
        $sql = "DESCRIBE ".$tablename;
        $res = $this->exec($sql);

        if(is_array($res)) {
            foreach ($res as $k => $v) {
                $tmp['fields'][] = $v['Field'];
                if($v['Extra'] == 'auto_increment') {
                    $tmp['pk'] = $v['Field'];
                }            
            }
        }
        return $tmp;
    }


    /**
     * 解析sql条件
     * @param  [type] $c [description]
     * @return [type]    [description]
     */
    public function parseCondition($c) {
        if(is_array($c)) {
            $ps = "";
            foreach ($c as $k => $v) {
                if(is_array($v)) {
                    $f = $this->_getExp($v[0]);

                    ($v[2] && in_array($v[2], array('AND','OR')) ) ? $l = " ".$v[2]." " : $l = " AND ";

                    $v0 = strtolower($v[0]);
                    if($v0 == 'like' || $v0 == "not like") {
                        $ps = $l.$k.$f."'%".checkSql($v[1])."%'";
                    } elseif($v0 == 'between' || $v0 == "not between") {
                        $ps = $l.$k.$f." ('".checkSql($v[1][0])."' AND '".checkSql($v[1][1])."')";
                    } else {
                        $ps = $l.$k.$f."'".checkSql($v[1])."'";
                    }
                } else {
                    $ps .= " and ".checkSql($k)." = '".checkSql($v)."'";
                }
            }            
            $ps = ltrim($ps);
            return substr($ps, 3, strlen($ps) -3);
        } else {
            return $c;
        }
    }

    /**
     * 解析数据
     * @param  [type] $d [description]
     * @return [type]    [description]
     */
    public function parseData($d) {
        
    }


    /**
     * 组装查询sql语句
     * @param  [type] $sql [description]
     * @return [type]      [description]
     */
    public function createSelectSql($fields, $tablename, $where="", $group="", $having="", $order="", $limit="") {
        $sql = "SELECT ";
        $fields     ?   $sql .= $fields." " : $sql .= " * "."\r\n";
        $sql .= " FROM ".$tablename."\r\n";        
        $where      ?   $sql .= " WHERE ".$where."\r\n" : '';
        $group      ?   $sql .= " GROUP BY ".$group."\r\n" : '';
        $having     ?   $sql .= " HAVING ".$having."\r\n" : '';
        $order      ?   $sql .= " ORDER BY ".$order."\r\n" : '';
        $limit      ?   $sql .= " LIMIT ".$limit."\r\n" : '';
        return $sql;
    }

    /**
     * 组装插入sql语句,支持replace
     * @return [type] [description]
     */
    public function createInserSQl($tablename,$data,$isreplace=false) {
        if(!$data) {
            return false;
        }
        $arr = get_object_vars($data);
        $field = $vals = '';
        foreach ($arr as $k => $v) {
            $fields .= ",".checkSql($k);
            $vals   .= ",'".checkSql($v)."'";
        }
        if($isreplace)
            $sql = "REPLACE INTO ".$tablename;
        else
            $sql = "INSERT INTO ".$tablename;
        $sql.= " (".trim($fields,',').") "."\r\n";
        $sql.= " VALUES "."\r\n";
        $sql.= " (".trim($vals,',').")";
        return $sql;
    }

    /**
     * 组装删除sql
     * @param  [type] $tablename [description]
     * @param  [type] $where     [description]
     * @param  [type] $limit     [description]
     * @return [type]            [description]
     */
    public function createDeleteSql($tablename, $where, $limit) {
        $sql = "DELETE FROM ".$tablename." \r\n";
        $sql.= " WHERE ".$where."\r\n";
        $limit ? $sql.=" LIMIT ".$limit."\r\n" : '';
        return $sql;
    }

    /**
     * 组装更新sql语句
     * @return [type] [description]
     */
    public function createUpdateSQl($tablename, $where, $data){
        $arr = get_object_vars($data);
        $sets = '';
        if(is_array($arr)) {
            foreach ($arr as $k => $v) {
                if(preg_match("/\+|-/", $v)) {
                    $sets .= $k."=".$v.",";
                }else {
                    $sets .= $k."='".$v."',";
                }
            }
        }

        $sets = trim($sets,',');

        $sql = "UPDATE ".$tablename." SET ".$sets." \r\n";
        $where ? $sql.= " WHERE ".$where : '';
        return $sql;
    }

    /**
     * 释放资源
     * @param  [type] $res [description]
     * @return [type]      [description]
     */
    public function freeResult($res) {
        mysql_free_result($res);
    }

    /**
     * 关闭链接
     * @return [type] [description]
     */
    public function close() {
        mysql_close($this->conn);
    }

    public function info() {
        return $this->sql;
    }

    /**
     * 获取错误信息
     * @return [type] [description]
     */
    public function error() {
        return $this->error;
    }

    /**
     * 获取错误代码
     * @return [type] [description]
     */
    public function errno() {
        return $this->errno;
    }

    /**
     * 解析数据
     * @param  [type] $res  [description]
     * @param  string $type [description]
     * @return [type]       [description]
     */
    protected function _fetchResult($res,$type = "assoc") {
        $ret = array();

        if($type == "assoc") {
            while ($row = mysql_fetch_assoc($res)) {
                $ret[] = $row;
            }
        } else {
            while ($row = mysql_fetch_array($res)) {
                $ret[] = $row;
            }
        }

        return $ret;
    }

    /**
     * 解析条件表达式
     * @return [type] [description]
     */
    protected function _getExp($e) {
        switch (strtolower($e)) {    
            case 'eq':
                $f = " = ";
                break;
            
            case 'neq':
                $f = " <> ";

            case 'gt':
                $f = " > ";
                break;

            case 'egt':
                $f = " >= ";
                break;

            case 'lt':
                $f = " < ";
                break;

            case 'elt':
                $f = " <= ";    
                break;

            case 'like':
                $f = " LIKE ";
                break;

            case 'between':
                $f = " BETWEEN ";
                break;
            case 'not between':
                $f = " NOT BETWEEN ";
                break;

            case 'in':
                $f = " IN ";
                break;

            case 'not in':
                $f = " NOT IN ";
                break;
        }
        return $f;
    }

}